package com.lv.common.network.config

import com.alibaba.android.arouter.launcher.ARouter
import com.blankj.utilcode.util.*
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import com.lv.common.network.support.YgxUtils
import com.lv.common.utils.ARoutUtils
import com.lv.common.utils.Constants
import com.lv.common.utils.LogUtil
import com.lv.common.utils.showToast
import okhttp3.CacheControl
import okhttp3.FormBody
import okhttp3.Interceptor
import okhttp3.Response
import okio.Buffer

/**
 * 作者： ygx
 * 创建日期：2022/1/20 9:37 PM
 * 签名： 天行健，君子以自强不息；地势坤，君子以厚德载物。
 *      _              _           _     _   ____  _             _ _
 *     / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 *    / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 *   / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 *  /_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
 *
 * You never know what you can do until you try !
 * ----------------------------------------------------------------
 * 项目相关，添加公共header的拦截器
 */
class YgxInterceptor : Interceptor {

    companion object {
        private val gson = GsonBuilder()
            .enableComplexMapKeySerialization()
            .create()
        private val mapType = object : TypeToken<Map<String, Any>>() {}.type
    }

    override fun intercept(chain: Interceptor.Chain): Response {
        val originRequest = chain.request()
        //附加的公共headers，封装clientInfo,deviceInfo等。也可以在post请求中，自定义封装headers的字段体内容
        //注意这里，服务器用于校验的字段，只能是以下的字段内容，可以缺失，但不能额外添加，因为服务端未做处理
//        var province = SPStaticUtils.getString(Constants.SP_KEY_ADDRESS_PROVINCE)
//        var city = SPStaticUtils.getString(Constants.SP_KEY_ADDRESS_CITY)
//        var area = SPStaticUtils.getString(Constants.SP_KEY_ADDRESS_AREA)
//        if (province.isNullOrEmpty()) {
//            province = "湖北"
//        }
//        if (city.isNullOrEmpty()) {
//            city = "武汉"
//        }
//        if (area.isNullOrEmpty()) {
//            area = "汉阳"
//        }
        val attachHeaders = mutableListOf<Pair<String, String>>(
            "Accept" to "" + "application/json",
            "version" to "" + AppUtils.getAppVersionName(),
            "platformModel" to "" + "Android",
            "app" to "" + "1",// 个 2  商 0 业 1
            "h_province" to "",
            "h_city" to "",
            "h_area" to "",
        )
        //token仅在有值的时候才传递，
        val tokenstr = ""
        val localToken = SPStaticUtils.getString(SP_KEY_USER_TOKEN, tokenstr)
        val refreshToken = SPStaticUtils.getString(SP_KEY_USER_REFRESH_TOKEN, tokenstr)
        val netId = SPStaticUtils.getString(SP_KEY_USER_ID, tokenstr)
        if (localToken.isNotEmpty()) {
            attachHeaders.add("token" to localToken)
            attachHeaders.add("refreshtoken" to refreshToken)
            attachHeaders.add("id" to netId)
        } else {
            attachHeaders.add("token" to "")
            attachHeaders.add("refreshtoken" to "")
            attachHeaders.add("id" to "")
        }
        val signHeaders = mutableListOf<Pair<String, String>>()
        signHeaders.addAll(attachHeaders)
        //get的请求，参数
        if (originRequest.method == "GET") {
            originRequest.url.queryParameterNames.forEach { key ->
                signHeaders.add(key to (originRequest.url.queryParameter(key) ?: ""))
            }
        }
        //post的请求 formBody形式，或json形式的，都需要将内部的字段，遍历出来，参与sign的计算
        val requestBody = originRequest.body
        if (originRequest.method == "POST") {
            //formBody
            if (requestBody is FormBody) {
                for (i in 0 until requestBody.size) {
                    signHeaders.add(requestBody.name(i) to requestBody.value(i))
                }
            }
            //json的body 需要将requestBody反序列化为json转为map application/json
            if (requestBody?.contentType()?.type == "application" && requestBody.contentType()?.subtype == "json") {
                kotlin.runCatching {
                    val buffer = Buffer()
                    requestBody.writeTo(buffer)
                    buffer.readByteString().utf8()
                }.onSuccess {
                    val map = gson.fromJson<Map<String, Any>>(it, mapType)
                    map.forEach { entry ->
                        // FIXME: 2020/8/25 value 目前json单层级
                        signHeaders.add(entry.key to entry.value.toString())
                    }
                }
            }
        }

        //todo 算法：都必须是非空参数！！！  sign = MD5（ascii排序后的 headers及params的key=value拼接&后，最后拼接appkey和value）//32位的大写,
        val signValue = signHeaders
            .sortedBy { it.first }
            .joinToString("&") { "${it.first}=${it.second}" }
            .plus("&appkey=$NET_CONFIG_APPKEY")

        val newBuilder = originRequest.newBuilder()
            .cacheControl(CacheControl.FORCE_NETWORK)
        attachHeaders.forEach { newBuilder.header(it.first, it.second) }
        newBuilder.header("sign", EncryptUtils.encryptMD5ToString(signValue))

        if (originRequest.method == "POST" && requestBody != null) {
            newBuilder.post(requestBody)
        } else if (originRequest.method == "GET") {
            newBuilder.get()
        }

        val response = chain.proceed(newBuilder.build())
        if (response.code == 401 || response.code == 203) {
            ARouter.getInstance().build(ARoutUtils.OneKeyLoginActivityURL).navigation()
        }
        return response
    }

}